package com.kznnc.data_structure.structure.linkedStructure;

/**
 * 怎么判断头结点  尾结点
 * 头结点的pre指针为null  尾节点的next指针为null
 */
public class DoubleLinedStructure {

    private Node head;

    private Node tail;

    private int size = 0;


    public void insertHead(Integer data) {
        Node node = new Node(data);
        if (head == null) {
            tail = node;
        } else {
            node.next = head;
            head.pre = node;
        }
        head = node;
        size++;
    }

    public void insertTail(Integer data) {
        Node node = new Node(data);
        if (tail == null) {
            head = node;
        } else {
            tail.next = node;
            node.pre = tail;
        }
        tail = node;
        size++;
    }

    public void removeHead() {
        if (head == null) {
            throw new RuntimeException("空指针");
        }
        if (head.next == null) {
            head = null;
            tail = null;
        } else {
            Node nextNode = head.next;
            nextNode.pre = null;
            head = nextNode;
        }
        size--;
    }


    public void removeTail() {
        if (tail == null) {
            throw new RuntimeException("空指针");
        }
        if (tail.pre == null) {
            head = null;
            tail = null;
        } else {
            Node preNode = tail.pre;
            preNode.next = null;
            tail = preNode;
        }
        size--;
    }

    public void removeIndex(Integer index) {
        if (index == 0) {
            removeHead();
        } else if (index == size - 1) {
            removeTail();
        } else {
            Node removeNode = tail;
            for (int i = size-1; i > index+1; i--) {
                removeNode = removeNode.pre;
            }
            Node preNode = removeNode.pre;
            preNode.next = removeNode.next;
            removeNode.next.pre = preNode;
            size--;
        }
    }

    public void insertData(Integer data) {
        insertTail(data);
    }

    public void insetIndex(Integer data, Integer index) {
        boolean checkIndex = index >= 0 && index < size;
        if (!checkIndex) {
            throw new RuntimeException("数组越界");
        }
        if (index == 0) {
            insertHead(data);
        } else if (index == size - 1) {
            insertTail(data);
        } else {
            Node node = head;
            for (int i = 0; i < index-1; i++) {
                node = node.next;
            }
            Node newNode = new Node(data);
            newNode.next = node.next;
            newNode.pre = node;
            node.next = newNode;
            size++;
        }
    }

    public Integer getIndexData(Integer index) {
        boolean checkIndex = index >= 0 && index < size;
        if (!checkIndex) {
            throw new RuntimeException("数组越界");
        }
        if (index == 0) {
            return head.data;
        }
        Node node = head;
        for (int i = 0; i < index; i++) {
            node = node.next;
        }
        return node.data;
    }


    public static void main(String[] args) {
        DoubleLinedStructure doubleLinedStructure = new DoubleLinedStructure();
        for (int i = 0; i < 5; i++) {
            doubleLinedStructure.insertData(i);
        }
        doubleLinedStructure.insetIndex(10,1);
        doubleLinedStructure.removeIndex(1);
        for (int i = 0; i < 4; i++) {
            System.out.println(doubleLinedStructure.getIndexData(i));
        }

    }

    static class Node {
        private Node pre;

        private Integer data;

        private Node next;

        public Node(Integer data) {
            this.data = data;
            this.pre = null;
            this.next = null;
        }

        public Node getPre() {
            return pre;
        }

        public void setPre(Node pre) {
            this.pre = pre;
        }

        public Integer getData() {
            return data;
        }

        public void setData(Integer data) {
            this.data = data;
        }

        public Node getNext() {
            return next;
        }

        public void setNext(Node next) {
            this.next = next;
        }
    }


}
